printf, seq: fix abort on large field width and precision#13460
printf, seq: fix abort on large field width and precision#13460eyupcanakman wants to merge 5 commits into
Conversation
A field width or precision above u16::MAX made Rust's formatting machinery panic, which the release build turns into a SIGABRT, so `printf '%70000d' 1` and `seq -f '%.70000f' 1 1` aborted where GNU pads the output. The %f formatter now assembles the decimal digits directly instead of going through bigdecimal's Display, which also fixes `printf '%.1000f' 1` printing `1` rather than `1.` and 1000 zeros (Display stops padding past 1000 digits). Padding is written in fixed chunks so a wide field costs no extra memory. Fixes uutils#12708
Merging this PR will degrade performance by 5.04%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Memory | cp_recursive_deep_tree[(120, 4)] |
532.7 KB | 699.2 KB | -23.82% |
| ⚡ | Simulation | seq_formatted |
94.7 ms | 80 ms | +18.37% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing eyupcanakman:fix/printf-large-width-precision-panic (7e19859) with main (4be96c1)
Footnotes
-
46 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
|
Please fix the job issue |
|
GNU testsuite comparison: |
unpadded and bigdecimal only appear in the new comments.
| decimal_digits(bd, precision) | ||
| } | ||
|
|
||
| /// Render `bd` in decimal notation with exactly `precision` fractional digits. |
There was a problem hiding this comment.
are you sure these long comments are valuable ?
There was a problem hiding this comment.
Trimmed them, kept only why each branch is there. Same in the tests.
Keep why each branch is there and drop the rest.
printfandseqabort with SIGABRT on a large field width or precision:Rust's formatting machinery panics once a dynamic width or precision passes
u16::MAX, and the release build turns that panic into an abort. GNU produces the padded output, so these now do too.While tracing it I found a second bug in the same path.
printf '%.1000f' 1printed1instead of1.and 1000 zeros, becausebigdecimal'sDisplaystops padding past 1000 digits. The%fformatter now assembles the digits directly, which fixes both. Padding is written in fixed chunks so a wide field costs no extra memory.#12620 uses the same chunked-padding approach for the width case. This also handles the large precision and the truncation, which #12620 and #12603 leave unfixed.
seq's own precision detection derives an unbounded value from the exponent text (seq 1e-3000000000 1e-3000000000), which this does not touch. That path is tracked in #13221.Fixes #12708